#include "driver.hpp"

namespace Driver
{
    Driver::Driver(argagg::parser_results &&args, const std::vector<std::string> &files) : m_args(args)
    {
        for (auto file : files)
        {
            m_files.push_back(removeFileSuffix(file));
        }
    }

    Driver::~Driver()
    {
    }

    int Driver::Preprocess()
    {

        std::string inputFile = "";
        std::string outputFile = "";
        std::string command = "";
        for (auto file : m_files)
        {
            inputFile = file + ".c";
            outputFile = file + ".i";
            command = "gcc -E -P " + inputFile + " -o " + outputFile;
            runSystemCommand(command);
        }

        return 0;
    }

    int Driver::Compile()
    {
        if (m_args["gcompile"])
        {
            std::string inputFile = "";
            std::string outputFile = "";
            std::string command = "";
            for (auto file : m_files)
            {
                inputFile = file + ".i";
                outputFile = file + ".o";
                command = "gcc -c " + inputFile + " -o " + outputFile;
                runSystemCommand(command);
            }
        }
        else
        {
            for (auto file : m_files)
            {
                std::string input = readFile(file + ".i");
                Lexer::Lexer lexer(input);
                lexer.Run();
                std::vector<Token::Token *> tokens = lexer.GetTokens();
            }
        }
        return 0;
    }

    int Driver::Assemble()
    {
        if (m_args["gcompile"])
        {
            std::string inputFile = "";
            std::string outputFile = "main";
            for (auto file : m_files)
            {
                inputFile += file + ".o ";
            }
            std::string command = "gcc " + inputFile + "-o " + outputFile;
            runSystemCommand(command);
        }
        else
        {
        }
        return 0;
    }

    int Driver::Run()
    {
        if (Preprocess() != 0)
        {
            return -1;
        }
        if (Compile() != 0)
        {
            return -1;
        }
        if (Assemble() != 0)
        {
            return -1;
        }
        return 0;
    }

    std::string Driver::removeFileSuffix(const std::string &filename)
    {
        size_t pos = filename.find_last_of('.');

        if (pos != std::string::npos)
        {
            return filename.substr(0, pos);
        }
        else
        {
            return filename;
        }
    }

    int Driver::runSystemCommand(const std::string &command)
    {
        return system(command.c_str());
    }

    std::string Driver::readFile(const std::string &fileName)
    {
        std::ifstream file(fileName);
        if (!file.is_open())
        {
            throw std::runtime_error("Failed to open file");
        }

        std::stringstream ss;
        ss << file.rdbuf();
        file.close();

        return ss.str();
    }
}